﻿using TrueSync;
using UnityEngine;

namespace HEFramework
{
    public static class ATKComponentSystem
    {
        [EntitySystem]
        public class ATKComponentAwakeSystem : AwakeSystem<ATKComponent>
        {
            protected override void Awake(ATKComponent _self)
            {
                _self.State = eATKState.Wait;
                _self.ATK_AT = 0;
                _self.ATK_DP = 0;
                _self.ATK_EP = 0;
                _self.ATK_DBS = 0;
            }
        }


        [EntitySystem]
        public class ATKComponentUpdateSystem : UpdateSystem<ATKComponent>
        {
            protected override void Update(ATKComponent _self)
            {
                var acA = _self.GetParentChild<AttributeComponent>();
                var tcA = _self.GetParentChild<TransformComponent>();
                var alc = _self.GetParentChild<AlertComponent>();
                if (acA == null || tcA == null || alc == null)
                {
                    return;
                }

                FP deltaTime = Time.deltaTime;

                var ATK_AT = Formula.TM(acA.P_ATK_AT);
                //限制上限
                TSMath.Min(_self.ATK_AT, ATK_AT);
                //攻击时间计算
                _self.ATK_AT -= deltaTime;
                if (_self.ATK_AT < 0)
                {
                    _self.ATK_AT = 0;
                }

                switch (_self.State)
                {
                    case eATKState.Wait:

                        if (_self.ATK_AT != 0)
                        {
                            return;
                        }

                        if (!_self.IsTargetInRange())
                        {
                            return;
                        }

                        _self.ATK_DP = 0;
                        _self.ATK_EP = 0;
                        _self.ATK_DBS = 0;
                        _self.State = eATKState.Before;
                        break;
                    case eATKState.Before:
                        var ATK_DP = Formula.TM(acA.P_ATK_DP);
                        TSMath.Min(_self.ATK_DP, ATK_DP);
                        if (_self.ATK_DP < ATK_DP)
                        {
                            _self.ATK_DP += deltaTime;
                            return;
                        }

                        var target = alc.Target.Entity;
                        var acB = target?.GetChild<AttributeComponent>();
                        if (acB != null)
                        {
                            //处理攻击
                            var sc = _self.GetParentChild<SkillComponent>();
                            if (sc != null)
                            {
                                sc.TriggerPassiveSkill(eSkillTriggerType.OnAttack);
                                sc.TriggerPassiveSkill(eSkillTriggerType.OnAttack, target);
                            }

                            if (acA.Attribute.P_ATK_E != 0)
                            {
                                var effect = _self.GetScene().AddChild<ATKEffect>();
                                effect.Execute(acA.Parent, acB.Parent);
                            }
                            else
                            {
                                acB.OnDamage(acA, acA.P_ATK.Value, ePowerType.Physics, true);
                            }
                        }

                        _self.ATK_AT = ATK_AT;
                        _self.ATK_DP = 0;
                        _self.State = eATKState.Empty;

                        break;
                    case eATKState.Empty:

                        var ATK_EP = Formula.TM(acA.P_ATK_EP);
                        TSMath.Min(_self.ATK_EP, ATK_EP);
                        if (_self.ATK_EP < ATK_EP)
                        {
                            _self.ATK_EP += deltaTime;
                            return;
                        }

                        _self.ATK_EP = 0;
                        _self.State = eATKState.After;
                        break;
                    case eATKState.After:
                        var ATK_DBS = Formula.TM(acA.P_ATK_DBS);
                        TSMath.Min(_self.ATK_DBS, ATK_DBS);
                        if (_self.ATK_DBS < ATK_DBS)
                        {
                            _self.ATK_DBS += deltaTime;
                            return;
                        }

                        _self.ATK_DBS = 0;
                        _self.State = eATKState.Wait;
                        break;
                }
            }
        }

        public static bool IsTargetInRange(this ATKComponent _self)
        {
            var acA = _self.GetParentChild<AttributeComponent>();
            var tcA = _self.GetParentChild<TransformComponent>();
            var alc = _self.GetParentChild<AlertComponent>();

            if (acA == null || tcA == null || alc == null)
            {
                return false;
            }

            var target = alc.Target.Entity;
            if (target == null)
            {
                return false;
            }

            var acB = target.GetChild<AttributeComponent>();
            var tcB = target.GetChild<TransformComponent>();
            if (acB == null || tcB == null)
            {
                return false;
            }

            FP dis = TSVector.Distance(tcA.P, tcB.P);
            //攻击距离
            if (Formula.LG(acA.P_ATK_RAG) >= dis)
            {
                return true;
            }

            return false;
        }
    }
}